//******************************************************************************
/**
 *
 * @file	fieldobj_move_2.c
 * @brief	フィールドOBJ　基本動作系その2
 * @author	kagaya
 * @data	05.07.21
 *
 */
//******************************************************************************
#include "common.h"
#include "fieldsys.h"
#include "fieldobj.h"

#include "ev_trainer.h"
#include "field_effect.h"
#include "pair_poke.h"

#if	GS_BTS5576_20090716_FIX

#define GRASS_ADD_VALID		//有効で連れポケ草登録する

#endif

//==============================================================================
//	define
//==============================================================================
///トレーナーペア　親移動停止
#define PAIR_TR_OYA_STA_BIT_STOP \
	(FLDOBJ_STA_BIT_ATTR_GET_ERROR		| \
	 FLDOBJ_STA_BIT_HEIGHT_GET_ERROR	| \
	 FLDOBJ_STA_BIT_PAUSE_MOVE)

//==============================================================================
//	typedef
//==============================================================================
//--------------------------------------------------------------
//	MV_PAIR_WORK構造体
//--------------------------------------------------------------
typedef struct
{
	u8 seq_no;												///<動作番号
	u8 jiki_init;											///<自機情報初期化完了
	//金銀から追加
	u8 MoveJumpCount;
	u8 JumpFrameCounter;

	s16 jiki_gx;											///<自機グリッド座標X
	s16 jiki_gz;											///<自機グリッド座標Z
	u16 jiki_ac;											///<自機アニメーションコード
	u16 eff_omit:1;											///<エフェクト省略フラグ
	u16 JmpTblNo:2;											///ジャンプテーブル 0:テーブル設定なし　1〜3：それぞれのジャンプテーブルインデックス
	u16 dummy:13;
}MV_PAIR_WORK;

#define MV_PAIR_WORK_SIZE (sizeof(MV_PAIR_WORK))

//--------------------------------------------------------------
//	MV_TR_PAIR_WORK構造体
//--------------------------------------------------------------
typedef struct
{
	u8 seq_no;											///<動作番号
	u8 oya_init;										///<親情報初期化完了
	s16 oya_gx;											///<親グリッド座標X
	s16 oya_gz;											///<親グリッド座標Z
	u16 oya_ac;											///<自機アニメーションコード
	FIELD_OBJ_PTR oyaobj;								///<親となるOBJ
}MV_TR_PAIR_WORK;

#define MV_TR_PAIR_WORK_SIZE (sizeof(MV_TR_PAIR_WORK))

//--------------------------------------------------------------
///	MV_HIDE_WORK構造体
//--------------------------------------------------------------
typedef struct
{
	u8 seq_no;
	u8 hide_type;
	u8 pulloff_flag;
	u8 dmy;
	EOA_PTR eoa_hide;
}MV_HIDE_WORK;

#define MV_HIDE_WORK_SIZE (sizeof(MV_HIDE_WORK))

//==============================================================================
//	プロトタイプ
//==============================================================================
int (* const DATA_PairMoveTbl[])( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work );
int (* const DATA_PairNoRateMoveTbl[])( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work );
int (* const DATA_PairNoRateCopyMoveTbl[])( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work );

static int Pair_WorkSetJikiSearch( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work );
static void Pair_WorkInit( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work );
static int Pair_JikiPosUpdateCheck( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work );
static void Pair_JikiPosSet( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work );
static u32 Pair_JikiAcmdCodeGet( FIELD_OBJ_PTR fldobj );
static u32 Pair_JikiAcmdCodeGet2( FIELD_OBJ_PTR fldobj );
static int Pair_JikiCheckAcmdSet( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work );
static int Pair_JikiCheckAcmdSet2( FIELD_OBJ_PTR fldobj );
static int Pair_JikiCheckAcmdSet3( FIELD_OBJ_PTR fldobj );

int (* const DATA_PairTrMoveTbl[])( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work );

static int PairTr_WorkSetOyaSearch( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work );
static void PairTr_WorkInit( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work, FIELD_OBJ_PTR oyaobj);
static int PairTr_OyaPosUpdateCheck( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work );
static void PairTr_OyaPosSet( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work );
static int PairTr_OyaCheckAcmdSet( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work );

static int Pair_GetJumpTblNo(const int inCode);

#ifdef GRASS_ADD_VALID
static void AddGrass( FIELD_OBJ_PTR fldobj );
#endif

int (* const DATA_HideMoveTbl[])( FIELD_OBJ_PTR fldobj, MV_HIDE_WORK *work );

//==============================================================================
//	MV_PAIR	自機連れ歩き
//==============================================================================
enum {
	PAIR_INIT_SEQ = 0,
	PAIR_MOVE_SEQ,
	PAIR_MOVE_JUMP_SEQ,
	PAIR_HOLD_SEQ,
};

//--------------------------------------------------------------
/**
 * MV_PAIR　初期化
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MovePair_Init( FIELD_OBJ_PTR fldobj )
{
	MV_PAIR_WORK *work = FieldOBJ_MoveProcWorkInit( fldobj, MV_PAIR_WORK_SIZE );
	Pair_WorkSetJikiSearch( fldobj, work );
	FieldOBJ_DrawStatusSet( fldobj, DRAW_STA_STOP );
	FieldOBJ_StatusBitOFF_Move( fldobj );
	FieldOBJ_StatusBitSet_FellowHit( fldobj, FALSE );
}

//--------------------------------------------------------------
/**
 * MV_PAIR　動作
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MovePair_Move( FIELD_OBJ_PTR fldobj )
{
	MV_PAIR_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );

	if( Pair_WorkSetJikiSearch(fldobj,work) == FALSE ){
		return;
	}
	//｜セーブ復帰時は、当たり判定ビットが落ちてしまうが、(FldOBJ_DataLoadStatusBitRecover関数)
	//↓ここで毎シンクセットしてあげれば、セーブから復帰してもOK
	FieldOBJ_StatusBitSet_FellowHit( fldobj, FALSE );
	while( DATA_PairMoveTbl[work->seq_no](fldobj,work) == TRUE ){};
}

//--------------------------------------------------------------
/**
 * MV_PAIR_NO_RATE　動作
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MovePairNoRate_Move( FIELD_OBJ_PTR fldobj )
{
	MV_PAIR_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );

	if( Pair_WorkSetJikiSearch(fldobj,work) == FALSE ){
		return;
	}

///	FieldOBJ_StatusBitSet_FellowHit( fldobj, FALSE );

	while( DATA_PairNoRateMoveTbl[work->seq_no](fldobj,work) == TRUE ){};
}

//--------------------------------------------------------------
/**
 * MV_PAIR_NO_RATE_CPY_MV　動作
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MovePairNoRate_CpyMove( FIELD_OBJ_PTR fldobj )
{
	MV_PAIR_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );

	if( Pair_WorkSetJikiSearch(fldobj,work) == FALSE ){
		return;
	}

///	FieldOBJ_StatusBitSet_FellowHit( fldobj, FALSE );

	while( DATA_PairNoRateCopyMoveTbl[work->seq_no](fldobj,work) == TRUE ){};
}

//--------------------------------------------------------------
/**
 * MV_PAIR 削除
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MovePair_Delete( FIELD_OBJ_PTR fldobj )
{
}

//--------------------------------------------------------------
/**
 * MV_PAIR 段差ジャンプフレームカウンタ
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	int フレーム
 */
//--------------------------------------------------------------
int FieldOBJ_GetMovePairJumpFrame( FIELD_OBJ_PTR fldobj )
{
	MV_PAIR_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );
	return work->JumpFrameCounter;
}

//--------------------------------------------------------------
/**
 * MV_PAIR 段差ジャンプテーブルナンバー
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	テーブルナンバー	0:テーブル指定なし 1〜3	テーブル番号（外で-1して、配列のインデックスにして使用してください）
 */
//--------------------------------------------------------------
int FieldOBJ_GetMovePairJumpTblNo( FIELD_OBJ_PTR fldobj )
{
	MV_PAIR_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );
	return work->JmpTblNo;
}

//--------------------------------------------------------------
/**
 * 出現エフェクト省略フラグ設定
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	none
 */
//--------------------------------------------------------------
void FieldOBJ_OmitMovePairDispEff( FIELD_OBJ_PTR fldobj )
{
	MV_PAIR_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );
	work->eff_omit = 1;
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモンの動作をキャンセルして、グリッド中央にセットする
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	none
 */
//--------------------------------------------------------------
void FieldObj_SetPairPokeGridCenter( FIELD_OBJ_PTR fldobj )
{
	int x,y,z;
	FIELDSYS_WORK *fsys = FieldOBJ_FieldSysWorkGet( fldobj );
	MV_PAIR_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );

	FieldOBJ_StatusBitOFF_Move( fldobj );
	FieldOBJ_StatusBitOFF_MoveEnd( fldobj );

	FieldOBJ_StatusBit_OFF( fldobj, FLDOBJ_STA_BIT_ACMD_END );
	FieldOBJ_AcmdCodeSet( fldobj, ACMD_NOT );
	FieldOBJ_AcmdSeqSet( fldobj, 0 );

	work->seq_no = PAIR_INIT_SEQ;
	fsys->PairPokeWork.AnimeCommand = 0;
	fsys->PairPokeWork.Code = AC_NONE;
	fsys->PairPokeWork.GridX = 0;
	fsys->PairPokeWork.GridZ = 0;

	//座標グリッド座標取得して、更新
	x = FieldOBJ_NowPosGX_Get(fldobj);
	y = FieldOBJ_NowPosGY_Get(fldobj);
	z = FieldOBJ_NowPosGZ_Get(fldobj);
	//座標セット
	FieldOBJ_GPosDirInit( fldobj, x, y, z, FieldOBJ_DirDispGet( fldobj ) );

}

//==============================================================================
//	MV_PAIR 動作
//==============================================================================

#include "fldeff_pokeballon.h"
//--------------------------------------------------------------
/**
 * Pair 0
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	int		TRUE=再帰要求
 */
//--------------------------------------------------------------
static int PairMove_Init( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work )
{
	FIELDSYS_WORK *fsys = FieldOBJ_FieldSysWorkGet( fldobj );
	FieldOBJ_StatusBitOFF_Move( fldobj );
	FieldOBJ_StatusBitOFF_MoveEnd( fldobj );

	if (fsys->PairPokeWork.Code == AC_START){
		fsys->PairPokeWork.Code = AC_READY;
		return ( FALSE );
	}else if(fsys->PairPokeWork.Code == AC_READY){
		Pair_JikiPosSet( fldobj, work );
		//自機の移動開始座標と自分の位置座標が同じ場合は、移動をホールドする
		if ( (fsys->PairPokeWork.GridX == FieldOBJ_NowPosGX_Get(fldobj))&&
				(fsys->PairPokeWork.GridZ == FieldOBJ_NowPosGZ_Get(fldobj)) ){
			fsys->PairPokeWork.Code = AC_NONE;
			work->seq_no = PAIR_HOLD_SEQ;
			//表示処理。非表示状態なら表示する
			if ( PairPoke_GetVanishFlgPrm( fldobj )&&(!work->eff_omit) ){
				//出現アニメ必要かで分岐
				if (PairPoke_GetAppAnmPrm(fldobj)){
					FE_MB_IO_Add( fldobj, MB_OUT );	//演出つき
					//出現アニメフラグ落とす
					PairPoke_SetAppAnmPrm(fldobj, 0);
				}else{
					PairPoke_StartVanish(fldobj, FALSE);
				}
#ifdef GRASS_ADD_VALID
				AddGrass( fldobj );
#endif
			}
			//段差ジャンプに対応する
			{
				BOOL player_jump;
				u32 code = Pair_JikiAcmdCodeGet( fldobj );
				player_jump = FieldOBJ_IsPlayerJumpAcmdCode( code );
				if (player_jump){
					PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( fsys );
					//ジャンプしたことを記憶する(自機ジャンプ方向を記憶)
					PairPoke_SetJumpDirPrm( fldobj, Player_DirGet( jiki ) );
				}
			}

			return( TRUE );
		}else{
			if( Pair_JikiCheckAcmdSet(fldobj, work) == TRUE ){
				//表示処理。非表示状態なら表示する
				if ( PairPoke_GetVanishFlgPrm( fldobj ) ){
					//出現アニメ必要かで分岐
					if (PairPoke_GetAppAnmPrm(fldobj)){
						FE_MB_IO_Add( fldobj, MB_OUT );	//演出つき
						//出現アニメフラグ落とす
						PairPoke_SetAppAnmPrm(fldobj, 0);
					}else{
						PairPoke_StartVanish(fldobj, FALSE);
					}
#ifdef GRASS_ADD_VALID
					AddGrass( fldobj );
#endif
				}
				FieldOBJ_StatusBitON_Move( fldobj );
				fsys->PairPokeWork.Code = AC_DONE;
				return( TRUE );
			}
		}
	}else if(fsys->PairPokeWork.Code == AC_DONE){
		fsys->PairPokeWork.Code = AC_NONE;
	}
#if 0
	if( Pair_JikiPosUpdateCheck(fldobj,work) == TRUE ){
		Pair_JikiPosSet( fldobj, work );

		if( Pair_JikiCheckAcmdSet(fldobj, work) == TRUE ){
			FieldOBJ_StatusBitON_Move( fldobj );
			return( TRUE );
		}
	}
#endif
	return( FALSE );
}

//--------------------------------------------------------------
/**
 * Pair 0
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	int		TRUE=再帰要求
 */
//--------------------------------------------------------------
static int PairMove_InitNoRate( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work )
{
	FieldOBJ_StatusBitOFF_Move( fldobj );
	FieldOBJ_StatusBitOFF_MoveEnd( fldobj );

	if( Pair_JikiPosUpdateCheck(fldobj,work) == TRUE ){
		Pair_JikiPosSet( fldobj, work );

		if ( PairPoke_GetVanishFlgPrm( fldobj ) ){
			//出現アニメ必要かで分岐
			if (PairPoke_GetAppAnmPrm(fldobj)){
				FE_MB_IO_Add( fldobj, MB_OUT );	//演出つき
				//出現アニメフラグ落とす
				PairPoke_SetAppAnmPrm(fldobj, 0);
			}else{
				PairPoke_StartVanish(fldobj, FALSE);
			}
#ifdef GRASS_ADD_VALID
			AddGrass( fldobj );
#endif
		}

		if( Pair_JikiCheckAcmdSet2(fldobj) == TRUE ){
			FieldOBJ_StatusBitON_Move( fldobj );
			work->seq_no++;
			return( TRUE );
		}
	}

	return( FALSE );
}

//--------------------------------------------------------------
/**
 * Pair 0
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	int		TRUE=再帰要求
 */
//--------------------------------------------------------------
static int PairMove_InitCopyMoveNoRate( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work )
{
	FieldOBJ_StatusBitOFF_Move( fldobj );
	FieldOBJ_StatusBitOFF_MoveEnd( fldobj );

	if( Pair_JikiPosUpdateCheck(fldobj,work) == TRUE ){
		Pair_JikiPosSet( fldobj, work );

		if( Pair_JikiCheckAcmdSet3(fldobj) == TRUE ){
			FieldOBJ_StatusBitON_Move( fldobj );
			work->seq_no++;
			return( TRUE );
		}
	}
	return( FALSE );
}

//--------------------------------------------------------------
/**
 * Pair 1
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	int		TRUE=再帰要求
 */
//--------------------------------------------------------------
static int PairMove_Move( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work )
{
	if( FieldOBJ_CmdAction(fldobj) == TRUE ){
		FieldOBJ_StatusBitOFF_Move( fldobj );
		work->seq_no = PAIR_INIT_SEQ;
	}

	return( FALSE );
}

//--------------------------------------------------------------
/**
 * Pair 2	ジャンプ特殊移動
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	int		TRUE=再帰要求
 */
//--------------------------------------------------------------
static int PairMove_MoveJump( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work )
{
	u32 code;

	if( FieldOBJ_CmdAction(fldobj) == TRUE ){
		if (++work->MoveJumpCount >= 2){
			FieldOBJ_StatusBitOFF_Move( fldobj );
			work->seq_no = PAIR_INIT_SEQ;
			work->JumpFrameCounter = 0;
			work->JmpTblNo = 0;
			return (FALSE);
		}else{
///			code = FieldOBJ_ParamGet( fldobj, FLDOBJ_PARAM_0 );
			code = PairPoke_GetAnmCode(fldobj);
			FieldOBJ_CmdSet( fldobj, code );
		}
	}
	work->JumpFrameCounter++;

	return( FALSE );
}

//--------------------------------------------------------------
/**
 * Pair 3	移動ホールド次の自機移動まで動かない
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	int		TRUE=再帰要求
 */
//--------------------------------------------------------------
static int PairMove_Hold( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work )
{
	FIELDSYS_WORK *fsys = FieldOBJ_FieldSysWorkGet( fldobj );
	PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( fsys );
	{
		//自機のアニメを監視	<<強制床移動の場合、ステートでは終了検出できないので、こちらで判定
		FIELD_OBJ_PTR player_fobj = Player_FieldOBJGet(jiki);
    	if( FieldOBJ_StatusBit_CheckEasy(player_fobj,FLDOBJ_STA_BIT_ACMD) == TRUE &&
        	FieldOBJ_StatusBit_CheckEasy(player_fobj,FLDOBJ_STA_BIT_ACMD_END) == TRUE ){
//			OS_Printf("アニメおわり\n");
			work->seq_no = PAIR_INIT_SEQ;
    	}
	}
	{
		//自機のステートを監視
		int state;
		state = Player_MoveStateGet( jiki );
		if (state == OBJ_MOVE_STATE_END){
			work->seq_no = PAIR_INIT_SEQ;
		}
	}
	return( FALSE );
}

//--------------------------------------------------------------
///	つれあるき動作テーブル	通常
//--------------------------------------------------------------
static int (* const DATA_PairMoveTbl[])( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work ) =
{
	PairMove_Init,
	PairMove_Move,
	PairMove_MoveJump,
	PairMove_Hold,
};

//--------------------------------------------------------------
///	つれあるき動作テーブル　イベントトレース連れ歩き
//--------------------------------------------------------------
static int (* const DATA_PairNoRateMoveTbl[])( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work ) =
{
	PairMove_InitNoRate,
	PairMove_Move,
	PairMove_MoveJump,
	PairMove_Hold,
};

//--------------------------------------------------------------
///	つれあるき動作テーブル イベント自機動作コピー
//--------------------------------------------------------------
static int (* const DATA_PairNoRateCopyMoveTbl[])( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work ) =
{
	PairMove_InitCopyMoveNoRate,
	PairMove_Move,
	PairMove_MoveJump,
	PairMove_Hold,
};

//==============================================================================
//	MV_PAIR　パーツ
//==============================================================================
//--------------------------------------------------------------
/**
 * 自機が存在するかチェック　存在するのであれば情報初期化
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	int		FALSE=存在していない
 */
//--------------------------------------------------------------
static int Pair_WorkSetJikiSearch( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work )
{
	CONST_FIELD_OBJ_SYS_PTR fos = FieldOBJ_FieldOBJSysGet( fldobj );
	FIELD_OBJ_PTR jikiobj = Player_FieldOBJSearch( fos );

	if( jikiobj == NULL ){
		work->jiki_init = FALSE;
		return( FALSE );
	}

	if( work->jiki_init == FALSE ){
		Pair_WorkInit( fldobj, work );
	}

	return( TRUE );
}

//--------------------------------------------------------------
/**
 * MV_PAIR_WORK初期化　自機がいる事前提
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	nothing
 */
//--------------------------------------------------------------
static void Pair_WorkInit( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work )
{
	FIELDSYS_WORK *fsys = FieldOBJ_FieldSysWorkGet( fldobj );
	PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( fsys );

	work->jiki_init = TRUE;
	work->jiki_gx = Player_NowGPosXGet( jiki );
	work->jiki_gz = Player_NowGPosZGet( jiki );
	work->jiki_ac = ACMD_NOT;
}

//--------------------------------------------------------------
/**
 * 自機座標更新チェック
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	int		TRUE=更新した
 */
//--------------------------------------------------------------
static int Pair_JikiPosUpdateCheck( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work )
{
	FIELDSYS_WORK *fsys = FieldOBJ_FieldSysWorkGet( fldobj );
	PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( fsys );

	if( jiki != NULL ){
		int gx = Player_NowGPosXGet( jiki );
		int gz = Player_NowGPosZGet( jiki );

		if( gx != work->jiki_gx || gz != work->jiki_gz ){
			return( TRUE );
		}
	}

	return( FALSE );
}

//--------------------------------------------------------------
/**
 * 自機座標セット
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	nothing
 */
//--------------------------------------------------------------
static void Pair_JikiPosSet( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work )
{
	FIELDSYS_WORK *fsys = FieldOBJ_FieldSysWorkGet( fldobj );
	PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( fsys );

	work->jiki_gx = Player_NowGPosXGet( jiki );
	work->jiki_gz = Player_NowGPosZGet( jiki );
}

//--------------------------------------------------------------
/**
 * 自機アニメコード取得
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	u32		アニメーションコード
 */
//--------------------------------------------------------------
static u32 Pair_JikiAcmdCodeGet( FIELD_OBJ_PTR fldobj )
{
	u32 code;
	FIELDSYS_WORK *fsys = FieldOBJ_FieldSysWorkGet( fldobj );
	PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( fsys );
///	code = FieldOBJ_AcmdCodeGet( Player_FieldOBJGet(jiki) );
	code = fsys->PairPokeWork.AnimeCommand;
	switch( code ){
	case AC_DASH_U_4F: code = AC_WALK_U_4F; break;
	case AC_DASH_D_4F: code = AC_WALK_D_4F; break;
	case AC_DASH_L_4F: code = AC_WALK_L_4F; break;
	case AC_DASH_R_4F: code = AC_WALK_R_4F; break;
	}

	return( code );
}

//--------------------------------------------------------------
/**
 * 自機アニメコード取得イベントアニメ（自機追従アニメ）時に
 * 自機フィールドＯＢＪアニメコードを直接参照
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	u32		アニメーションコード
 */
//--------------------------------------------------------------
static u32 Pair_JikiAcmdCodeGet2( FIELD_OBJ_PTR fldobj )
{
	u32 code;
	FIELDSYS_WORK *fsys = FieldOBJ_FieldSysWorkGet( fldobj );
	PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( fsys );
	{
		FIELD_OBJ_PTR player_obj_ptr;
		player_obj_ptr = Player_FieldOBJGet( jiki );
		code = FieldOBJ_AcmdCodeGet(player_obj_ptr);
	}
	switch( code ){
	case AC_DASH_U_4F: code = AC_WALK_U_4F; break;
	case AC_DASH_D_4F: code = AC_WALK_D_4F; break;
	case AC_DASH_L_4F: code = AC_WALK_L_4F; break;
	case AC_DASH_R_4F: code = AC_WALK_R_4F; break;
	}

	return( code );
}

//--------------------------------------------------------------
/**
 * 自機アニメコード、方向を取得しアニメーションコマンドをセット
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	int		TRUE=セットできた FALSE=重なりによりセットできない
 */
//--------------------------------------------------------------
static int Pair_JikiCheckAcmdSet( FIELD_OBJ_PTR fldobj, MV_PAIR_WORK *work )
{
	u8 next_seq;
	FIELDSYS_WORK *fsys = FieldOBJ_FieldSysWorkGet( fldobj );
	PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( fsys );
	int gx = FieldOBJ_NowPosGX_Get( fldobj );
	int gz = FieldOBJ_NowPosGZ_Get( fldobj );
	int jx = Player_OldGPosXGet( jiki );
	int jz = Player_OldGPosZGet( jiki );

	if( gx != jx || gz != jz ){
		u32 code = Pair_JikiAcmdCodeGet( fldobj );
		int dir = FieldOBJTool_DirRange( gx, gz, jx, jz );
		u8 jump_dir = PairPoke_GetJumpDirPrm( fldobj );
		BOOL player_jump = FieldOBJ_IsPlayerJumpAcmdCode( code );
		next_seq = PAIR_MOVE_SEQ;
		//自機がジャンプ直後ならば、連れ歩きポケモンをジャンプ移動
		if (jump_dir){  //上向き段差は無いので、DIR_UPでif文が書ける。DIR_UP以外ならばif文内の処理を行う
			if ( player_jump ){
				//段差飛び越え
				code = FieldOBJ_CodeChgToWalk(jump_dir);
				//保存しておいた方向と、自機の移動速度に応じて、アニメコマンドを作成
				code = PairPoke_ChangeWalkToJumpCode(jump_dir, code);
				//自機の移動速度に応じて、ジャンプテーブルを確定(ジャンプ中のためスピードが確定する)
				work->JmpTblNo = Pair_GetJumpTblNo(code);
				//コード保存
///				FieldOBJ_ParamSet( fldobj, code, FLDOBJ_PARAM_0 );
				PairPoke_SetAnmCode(fldobj, code);
				next_seq = PAIR_MOVE_JUMP_SEQ;	//シーケンスを書き換え
				work->MoveJumpCount = 0;
				work->JumpFrameCounter = 0;
				//ジャンプしたことを記憶する(自機ジャンプ方向を記憶)
				PairPoke_SetJumpDirPrm( fldobj, Player_DirGet( jiki ) );
			}else{
				if ( !Player_MoveBitCheck_Step( jiki ) ){
					return FALSE;
				}
				//保存しておいた方向と、自機の移動速度に応じて、アニメコマンドを作成
				code = PairPoke_ChangeWalkToJumpCode(jump_dir, code);
				//自機の移動速度に応じて、ジャンプテーブルを確定(自機が歩き状態かダッシュ状態かで分岐)
				work->JmpTblNo = Pair_GetJumpTblNo(code);
				//コード保存
///				FieldOBJ_ParamSet( fldobj, code, FLDOBJ_PARAM_0 );
				PairPoke_SetAnmCode(fldobj, code);
				next_seq = PAIR_MOVE_JUMP_SEQ;	//シーケンスを書き換え
				work->MoveJumpCount = 0;
				work->JumpFrameCounter = 0;

				PairPoke_SetJumpDirPrm( fldobj, 0 );	//上向き段差はないのでクリア値として0==DIR_UPを入れとく
			}
		}else{
			//自機が段差飛び越えするかをチェック
			if (player_jump){
				//段差飛び越え
				code = FieldOBJ_CodeChgToWalk(dir);
				//ジャンプしたことを記憶する(自機ジャンプ方向を記憶)
				PairPoke_SetJumpDirPrm( fldobj, Player_DirGet( jiki ) );

			}else{
				code = FieldOBJ_AcmdCodeDirChange( dir, code );
			}
		}

		FieldOBJ_CmdSet( fldobj, code );
		//動作シーケンスへ
		work->seq_no = next_seq;
		return( TRUE );
	}

	return( FALSE );
}

//==============================================================================
//	MV_PAIR_NO_RATE　パーツ
//==============================================================================
//--------------------------------------------------------------
/**
 * 自機アニメコード、方向を取得しアニメーションコマンドをセット
 * イベントアニメ(自機追従アニメ)用
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	int		TRUE=セットできた FALSE=重なりによりセットできない
 */
//--------------------------------------------------------------
static int Pair_JikiCheckAcmdSet2( FIELD_OBJ_PTR fldobj )
{
	FIELDSYS_WORK *fsys = FieldOBJ_FieldSysWorkGet( fldobj );
	PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( fsys );
	int gx = FieldOBJ_NowPosGX_Get( fldobj );
	int gz = FieldOBJ_NowPosGZ_Get( fldobj );
	int jx = Player_OldGPosXGet( jiki );
	int jz = Player_OldGPosZGet( jiki );

	if( gx != jx || gz != jz ){
		u32 code = Pair_JikiAcmdCodeGet2( fldobj );
		int dir = FieldOBJTool_DirRange( gx, gz, jx, jz );
		if (code == MV_CODE_NOT){
			OS_Printf("エラーコード検出\n");
			GF_ASSERT(0);
			return( FALSE );
		}
		code = FieldOBJ_AcmdCodeDirChange( dir, code );
		FieldOBJ_CmdSet( fldobj, code );

		return( TRUE );
	}

	return( FALSE );
}

//--------------------------------------------------------------
/**
 * 自機アニメコード、方向を取得しアニメーションコマンドをセット
 * イベントアニメ(自機追従アニメ)用 自機アニメコードをコピーして動く
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	int		TRUE=セットできた FALSE=重なりによりセットできない
 */
//--------------------------------------------------------------
static int Pair_JikiCheckAcmdSet3( FIELD_OBJ_PTR fldobj )
{
	FIELDSYS_WORK *fsys = FieldOBJ_FieldSysWorkGet( fldobj );
	PLAYER_STATE_PTR jiki = Player_FieldSysWorkPlayerGet( fsys );
	int gx = FieldOBJ_NowPosGX_Get( fldobj );
	int gz = FieldOBJ_NowPosGZ_Get( fldobj );
	int jx = Player_OldGPosXGet( jiki );
	int jz = Player_OldGPosZGet( jiki );

	if( /*gx != jx || gz != jz*/1){	//自機と重なっていても動くように変更
		u32 code = Pair_JikiAcmdCodeGet2( fldobj );
		if (code == ACMD_NOT){
			//アニメーションコマンドなし
			return( FALSE );
		}
		FieldOBJ_CmdSet( fldobj, code );

		return( TRUE );
	}

	return( FALSE );
}

//==============================================================================
//	MV_TR_PAIR トレーナー連れ歩き
//==============================================================================
//--------------------------------------------------------------
/**
 * MV_TR_PAIR　初期化
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MovePairTr_Init( FIELD_OBJ_PTR fldobj )
{
	MV_TR_PAIR_WORK *work = FieldOBJ_MoveProcWorkInit( fldobj, MV_TR_PAIR_WORK_SIZE );
	PairTr_WorkSetOyaSearch( fldobj, work );
	FieldOBJ_DrawStatusSet( fldobj, DRAW_STA_STOP );
	FieldOBJ_StatusBitOFF_Move( fldobj );

//	FieldOBJ_StatusBitSet_FellowHit( fldobj, FALSE );
	work->oya_init = FALSE;
}

//--------------------------------------------------------------
/**
 * MV_TR_PAIR　動作
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MovePairTr_Move( FIELD_OBJ_PTR fldobj )
{
	MV_TR_PAIR_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );

	if( PairTr_WorkSetOyaSearch(fldobj,work) == FALSE ){
		return;
	}

//	FieldOBJ_StatusBitSet_FellowHit( fldobj, FALSE );
	while( DATA_PairTrMoveTbl[work->seq_no](fldobj,work) == TRUE ){};
}

//--------------------------------------------------------------
/**
 * MV_TR_PAIR 削除
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MovePairTr_Delete( FIELD_OBJ_PTR fldobj )
{
}

//--------------------------------------------------------------
/**
 * MV_TR_PAIR　復帰
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MovePairTr_Return( FIELD_OBJ_PTR fldobj )
{
	MV_TR_PAIR_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );
	work->oya_init = 0;
//	PairTr_WorkSetOyaSearch( fldobj, work );
}

//==============================================================================
//	MV_TR_PAIR 動作
//==============================================================================
//--------------------------------------------------------------
/**
 * Pair 0
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_TR_PAIR_WORK
 * @retval	int		TRUE=再帰要求
 */
//--------------------------------------------------------------
static int PairTrMove_Init( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work )
{
	FieldOBJ_StatusBitOFF_Move( fldobj );
	FieldOBJ_StatusBitOFF_MoveEnd( fldobj );

	if( PairTr_OyaPosUpdateCheck(fldobj,work) == TRUE ){
		if( PairTr_OyaCheckAcmdSet(fldobj,work) == TRUE ){
//			PairTr_OyaPosSet( fldobj, work );
			FieldOBJ_StatusBitON_Move( fldobj );
			work->seq_no++;
			return( TRUE );
		}
	}

	return( FALSE );
}

//--------------------------------------------------------------
/**
 * Pair 1
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	int		TRUE=再帰要求
 */
//--------------------------------------------------------------
static int PairTrMove_Move( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work )
{
	if( FieldOBJ_CmdAction(fldobj) == FALSE ){
		return( FALSE );
	}

	FieldOBJ_StatusBitOFF_Move( fldobj );
	work->seq_no = 0;
	return( FALSE );
}

//--------------------------------------------------------------
///	つれあるき動作テーブル
//--------------------------------------------------------------
static int (* const DATA_PairTrMoveTbl[])( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work ) =
{
	PairTrMove_Init,
	PairTrMove_Move,
};

//==============================================================================
//	MV_TR_PAIR　パーツ
//==============================================================================
//--------------------------------------------------------------
/**
 * 対象がペア動作かどうか。ペア動作であれば相方を探す
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	FIELD_OBJ_PTR　相方のFIELD_OBJ_PTR、NULL=ペア動作ではない
 */
//--------------------------------------------------------------
FIELD_OBJ_PTR FieldOBJ_MovePairSearch( FIELD_OBJ_PTR fldobj )
{
	int no = 0;
	int type = FieldOBJ_EventTypeGet( fldobj );
	int zone_id = FieldOBJ_ZoneIDGet( fldobj );
	u32 trid = EvTrainerFldOBJTrainerIDGet( fldobj );
	CONST_FIELD_OBJ_SYS_PTR fos = FieldOBJ_FieldOBJSysGet( fldobj );
	FIELD_OBJ_PTR pair;

	switch( type ){
	case EV_TYPE_TRAINER:
	case EV_TYPE_TRAINER_EYEALL:
	case EV_TYPE_ITEM:
	case EV_TYPE_TRAINER_KYORO:
	case EV_TYPE_TRAINER_SPIN_STOP_L:
	case EV_TYPE_TRAINER_SPIN_STOP_R:
	case EV_TYPE_TRAINER_SPIN_MOVE_L:
	case EV_TYPE_TRAINER_SPIN_MOVE_R:
		while( FieldOBJSys_FieldOBJSearch(fos,&pair,&no,FLDOBJ_STA_BIT_USE) == TRUE ){
			if( fldobj != pair && FieldOBJ_ZoneIDGet(pair) == zone_id ){
				if( EvTrainerFldOBJTrainerIDGet(pair) == trid ){
					return( pair );
				}
			}
		}
	}

	return( NULL );
}

//--------------------------------------------------------------
/**
 * 親が存在するかチェック　存在するのであれば情報初期化
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_TR_PAIR_WORK
 * @retval	int		FALSE=存在していない
 */
//--------------------------------------------------------------
static int PairTr_WorkSetOyaSearch( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work )
{
	int no,zone;
	u32 trid;
	FIELD_OBJ_PTR oyaobj;
	CONST_FIELD_OBJ_SYS_PTR fos = FieldOBJ_FieldOBJSysGet( fldobj );

	no = 0;
	zone = FieldOBJ_ZoneIDGet( fldobj );
	trid = EvTrainerFldOBJTrainerIDGet( fldobj );

	while( FieldOBJSys_FieldOBJSearch(fos,&oyaobj,&no,FLDOBJ_STA_BIT_USE) == TRUE ){
		if( fldobj != oyaobj &&
			FieldOBJ_ZoneIDGet(oyaobj) == zone &&
			EvTrainerFldOBJTrainerIDGet(oyaobj) == trid ){

			if( work->oya_init == FALSE ){
				PairTr_WorkInit( fldobj, work, oyaobj );
			}

			return( TRUE );
		}
	}

	work->oya_init = FALSE;
	return( FALSE );
}

//--------------------------------------------------------------
/**
 * MV_TR_PAIR_WORK初期化　親がいる事前提
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_TR_PAIR_WORK
 * @retval	nothing
 */
//--------------------------------------------------------------
static void PairTr_WorkInit( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work, FIELD_OBJ_PTR oyaobj )
{
	work->oya_init = TRUE;
	work->oya_gx = FieldOBJ_NowPosGX_Get( oyaobj );
	work->oya_gz = FieldOBJ_NowPosGZ_Get( oyaobj );
	work->oya_ac = ACMD_NOT;
	work->oyaobj = oyaobj;
}

//--------------------------------------------------------------
/**
 * 親座標更新チェック
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	int		TRUE=更新した
 */
//--------------------------------------------------------------
static int PairTr_OyaPosUpdateCheck( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work )
{
	FIELD_OBJ_PTR oyaobj = work->oyaobj;
	int gx = FieldOBJ_NowPosGX_Get( fldobj );
	int gz = FieldOBJ_NowPosGZ_Get( fldobj );
	int ngx = FieldOBJ_OldPosGX_Get( oyaobj );
	int ngz = FieldOBJ_OldPosGZ_Get( oyaobj );

	if( (gx != ngx || gz != ngz) &&
		(FieldOBJ_StatusBitCheck_Move(oyaobj) == TRUE ||
		FieldOBJ_StatusBit_Check(oyaobj,PAIR_TR_OYA_STA_BIT_STOP) == 0) ){
		return( TRUE );
	}

	return( FALSE );
}

#if 0	//相方の高さを考慮していない
static int PairTr_OyaPosUpdateCheck( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work )
{
	FIELD_OBJ_PTR oyaobj = work->oyaobj;
	int gx = FieldOBJ_NowPosGX_Get( fldobj );
	int gz = FieldOBJ_NowPosGZ_Get( fldobj );
	int ngx = FieldOBJ_OldPosGX_Get( oyaobj );
	int ngz = FieldOBJ_OldPosGZ_Get( oyaobj );

	if( (gx != ngx || gz != ngz) &&
		FieldOBJ_StatusBit_CheckEasy(oyaobj,FLDOBJ_STA_BIT_ATTR_GET_ERROR) == FALSE &&
		FieldOBJ_StatusBit_CheckEasy(oyaobj,FLDOBJ_STA_BIT_PAUSE_MOVE) == FALSE ){
		return( TRUE );
	}

	return( FALSE );
}
#endif

#if 0
static int PairTr_OyaPosUpdateCheck( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work )
{
	FIELD_OBJ_PTR oyaobj = work->oyaobj;
	int gx = FieldOBJ_NowPosGX_Get( oyaobj );
	int gz = FieldOBJ_NowPosGZ_Get( oyaobj );

	if( (gx != work->oya_gx || gz != work->oya_gz) &&
		FieldOBJ_StatusBit_CheckEasy(oyaobj,FLDOBJ_STA_BIT_ATTR_GET_ERROR) == FALSE &&
		FieldOBJ_StatusBit_CheckEasy(oyaobj,FLDOBJ_STA_BIT_PAUSE_MOVE) == FALSE ){
		return( TRUE );
	}

	return( FALSE );
}
#endif

//--------------------------------------------------------------
/**
 * 親座標セット
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_PAIR_WORK
 * @retval	nothing
 */
//--------------------------------------------------------------
static void PairTr_OyaPosSet( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work )
{
	work->oya_gx = FieldOBJ_NowPosGX_Get( work->oyaobj );
	work->oya_gz = FieldOBJ_NowPosGZ_Get( work->oyaobj );
}

//--------------------------------------------------------------
/**
 * 親アニメコード、方向を取得しアニメーションコマンドをセット
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	int		TRUE=セットできた FALSE=重なりによりセットできない
 */
//--------------------------------------------------------------
static int PairTr_OyaCheckAcmdSet( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work )
{
	int gx = FieldOBJ_NowPosGX_Get( fldobj );
	int gz = FieldOBJ_NowPosGZ_Get( fldobj );
	int ngx = FieldOBJ_NowPosGX_Get( work->oyaobj );
	int ngz = FieldOBJ_NowPosGZ_Get( work->oyaobj );
	int ogx = FieldOBJ_OldPosGX_Get( work->oyaobj );
	int ogz = FieldOBJ_OldPosGZ_Get( work->oyaobj );
	int dir;

	if( gx == ngx && gz == ngz ){
		return( FALSE );
	}

	dir = FieldOBJTool_DirRange( gx, gz, ogx, ogz );
	gx += FieldOBJ_DirAddValueGX( dir );
	gz += FieldOBJ_DirAddValueGZ( dir );

	if( gx != ngx || gz != ngz ){
		u32 code = AC_WALK_U_8F;
		code = FieldOBJ_AcmdCodeDirChange( dir, code );
		FieldOBJ_CmdSet( fldobj, code );
		return( TRUE );
	}

	return( FALSE );
}

#if 0
static int PairTr_OyaCheckAcmdSet( FIELD_OBJ_PTR fldobj, MV_TR_PAIR_WORK *work )
{
	int gx = FieldOBJ_NowPosGX_Get( fldobj );
	int gz = FieldOBJ_NowPosGZ_Get( fldobj );
	int ngx = FieldOBJ_NowPosGX_Get( work->oyaobj );
	int ngz = FieldOBJ_NowPosGZ_Get( work->oyaobj );
	int ogx = FieldOBJ_OldPosGX_Get( work->oyaobj );
	int ogz = FieldOBJ_OldPosGZ_Get( work->oyaobj );
	int sx,sz;

	if( gx == ngx && gz == ngz ){
		return( FALSE );
	}

	sx = gx - ogx;
	if( sx < 0 ){ sx = -sx; }
	sz = gz - ogz;
	if( sz < 0 ){ sz = -sz; }

	if( sx || sz ){
		int dir = FieldOBJTool_DirRange( gx, gz, ogx, ogz );
		gx += FieldOBJ_DirAddValueGX( dir );
		gz += FieldOBJ_DirAddValueGZ( dir );

		if( gx != ngx && gz != ngz ){
			u32 code = AC_WALK_U_8F;
			code = FieldOBJ_AcmdCodeDirChange( dir, code );
			FieldOBJ_CmdSet( fldobj, code );
			return( TRUE );
		}
	}

	return( FALSE );
}
#endif

//==============================================================================
//	MV_HIDE_SNOW　隠れ蓑　雪
//==============================================================================
//--------------------------------------------------------------
/**
 * MV_HIDE 初期化
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	type	HIDETYPE
 * @retval	nothing
 */
//--------------------------------------------------------------
static void FldOBJ_MoveHide_Init( FIELD_OBJ_PTR fldobj, HIDETYPE type )
{
	MV_HIDE_WORK *work = FieldOBJ_MoveProcWorkInit( fldobj, MV_HIDE_WORK_SIZE );
	work->hide_type = type;
	FieldOBJ_DrawStatusSet( fldobj, DRAW_STA_STOP );
	FieldOBJ_StatusBitOFF_Move( fldobj );
	FieldOBJ_StatusBit_ON( fldobj, FLDOBJ_STA_BIT_SHADOW_VANISH );

	{															//高さ落とす
		VecFx32 offs = { 0, NUM_FX32(-32), 0 };
		FieldOBJ_VecDrawOffsSet( fldobj, &offs );
	}
}

//--------------------------------------------------------------
/**
 * MV_HIDE_SNOW 初期化
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MoveHideSnow_Init( FIELD_OBJ_PTR fldobj )
{
	FldOBJ_MoveHide_Init( fldobj, HIDE_SNOW );
}

//--------------------------------------------------------------
/**
 * MV_HIDE_SAND 初期化
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MoveHideSand_Init( FIELD_OBJ_PTR fldobj )
{
	FldOBJ_MoveHide_Init( fldobj, HIDE_SAND );
}

//--------------------------------------------------------------
/**
 * MV_HIDE_GRND 初期化
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MoveHideGround_Init( FIELD_OBJ_PTR fldobj )
{
	FldOBJ_MoveHide_Init( fldobj, HIDE_GROUND );
}

//--------------------------------------------------------------
/**
 * MV_HIDE_KUSA 初期化
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MoveHideKusa_Init( FIELD_OBJ_PTR fldobj )
{
	FldOBJ_MoveHide_Init( fldobj, HIDE_GRASS );
}

//--------------------------------------------------------------
/**
 * MV_HIDE 動作
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MoveHide_Move( FIELD_OBJ_PTR fldobj )
{
	MV_HIDE_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );
	while( DATA_HideMoveTbl[work->seq_no](fldobj,work) == TRUE ){};
}

//--------------------------------------------------------------
/**
 * MV_HIDE 削除
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MoveHide_Delete( FIELD_OBJ_PTR fldobj )
{
	EOA_PTR eoa = FieldOBJ_MoveHideEoaPtrGet( fldobj );
	if( eoa != NULL ){ FE_EoaDelete( eoa ); }
}

//--------------------------------------------------------------
/**
 * MV_HIDE 復帰
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MoveHide_Return( FIELD_OBJ_PTR fldobj )
{
	MV_HIDE_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );

	work->seq_no = 0;

	FieldOBJ_MoveHideEoaPtrSet( fldobj, NULL );

	if( work->pulloff_flag == FALSE ){
		VecFx32 offs = { 0, NUM_FX32(-32), 0 };
		FieldOBJ_VecDrawOffsSet( fldobj, &offs );
		//add pl
		FieldOBJ_StatusBit_ON( fldobj, FLDOBJ_STA_BIT_SHADOW_VANISH );
	}
}

//==============================================================================
//	MV_HIDE 動作
//==============================================================================
//--------------------------------------------------------------
/**
 * hide 0
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_HIDE_WORK
 * @retval	int		TRUE=再帰要求
 */
//--------------------------------------------------------------
static int HideMove_Init( FIELD_OBJ_PTR fldobj, MV_HIDE_WORK *work )
{
	if( work->pulloff_flag == FALSE ){
		EOA_PTR eoa = FE_FldOBJHide_Add( fldobj, work->hide_type );
		FieldOBJ_MoveHideEoaPtrSet( fldobj, eoa );
	}

	FieldOBJ_StatusBitOFF_Move( fldobj );
	FieldOBJ_StatusBitOFF_MoveEnd( fldobj );

	work->seq_no++;
	return( FALSE );
}

//--------------------------------------------------------------
/**
 * hide 1
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	work	MV_HIDE_WORK
 * @retval	int		TRUE=再帰要求
 */
//--------------------------------------------------------------
static int HideMove_Move( FIELD_OBJ_PTR fldobj, MV_HIDE_WORK *work )
{
	if( work->pulloff_flag == FALSE ){
		EOA_PTR eoa = FieldOBJ_MoveHideEoaPtrGet( fldobj );

		if( eoa == NULL ){
			if( FieldOBJ_StatusBit_DrawInitCompCheck(fldobj) == TRUE ){
				eoa = FE_FldOBJHide_Add( fldobj, work->hide_type );
				FieldOBJ_MoveHideEoaPtrSet( fldobj, eoa );
			}
		}

		//add pl 常に影を消す
		FieldOBJ_StatusBit_ON( fldobj, FLDOBJ_STA_BIT_SHADOW_VANISH );
	}

	return( FALSE );
}

//--------------------------------------------------------------
///	MV_HIDE 動作テーブル
//--------------------------------------------------------------
static int (* const DATA_HideMoveTbl[])( FIELD_OBJ_PTR fldobj, MV_HIDE_WORK *work ) =
{
	HideMove_Init,
	HideMove_Move,
};

//==============================================================================
//	MV_HIDE パーツ
//==============================================================================
//--------------------------------------------------------------
/**
 * MV_HIDE 隠れ蓑EOA_PTRセット
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	eoa		EOA_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MoveHideEoaPtrSet( FIELD_OBJ_PTR fldobj, EOA_PTR eoa )
{
	MV_HIDE_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );
	work->eoa_hide = eoa;
}

//--------------------------------------------------------------
/**
 * MV_HIDE 隠れ蓑EOA_PTR取得
 * @param	fldobj	FIELD_OBJ_PTR
 * @param	eoa		EOA_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
EOA_PTR FieldOBJ_MoveHideEoaPtrGet( FIELD_OBJ_PTR fldobj )
{
	MV_HIDE_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );
	return( work->eoa_hide );
}

//--------------------------------------------------------------
/**
 * MV_HIDE 隠れ蓑、脱いだ状態に
 * @param	fldobj	FIELD_OBJ_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
void FieldOBJ_MoveHidePullOffFlagSet( FIELD_OBJ_PTR fldobj )
{
	MV_HIDE_WORK *work = FieldOBJ_MoveProcWorkGet( fldobj );
	work->pulloff_flag = TRUE;
}

//--------------------------------------------------------------
/**
 * 移動コマンドから連れ歩きのジャンプテーブルナンバーを取得する
 *
 * @param	code	アニメコマンド
 *
 * @retval	u8		ジャンプテーブルナンバー
 */
//--------------------------------------------------------------
static int Pair_GetJumpTblNo(const int inCode)
{
	u8 i;
	int tbl_8f[] = {AC_WALK_U_8F,AC_WALK_D_8F,AC_WALK_L_8F,AC_WALK_R_8F};
	int tbl_4f[] = {AC_WALK_U_4F,AC_WALK_D_4F,AC_WALK_L_4F,AC_WALK_R_4F};
	int tbl_2f[] = {AC_WALK_U_2F,AC_WALK_D_2F,AC_WALK_L_2F,AC_WALK_R_2F};

	for(i=0;i<DIR_4_MAX;i++){
		if (tbl_8f[i] == inCode){
			return 3;
		}
	}

	for(i=0;i<DIR_4_MAX;i++){
		if (tbl_4f[i] == inCode){
			return 2;
		}
	}

	for(i=0;i<DIR_4_MAX;i++){
		if (tbl_2f[i] == inCode){
			return 1;
		}
	}

	GF_ASSERT(0);
	return 0;
}

#ifdef GRASS_ADD_VALID
//--------------------------------------------------------------
/**
 * 自機の一歩移動で連れ歩きの草追加
 *
 * @param	fldobj		連れ歩きフィールドOBJ
 *
 * @retval	none
 */
//--------------------------------------------------------------
static void AddGrass( FIELD_OBJ_PTR fldobj )
{
	int x,z;
	u16 attr;
	FIELDSYS_WORK *fsys = FieldOBJ_FieldSysWorkGet( fldobj );
	//足元のアトリビュートを調べる
	x = FieldOBJ_NowPosGX_Get(fldobj);
	z = FieldOBJ_NowPosGZ_Get(fldobj);

	attr = GetAttributeLSB( fsys, x, z );
	if( MATR_IsGrass(attr) == TRUE ){
		FE_FldOBJGrass_Add( fldobj, FALSE );
	}else if(  MATR_IsLongGrass(attr) == TRUE ){
		FE_FldOBJLGrass_Add( fldobj, FALSE );
	}

	//大きいポケのときは後ろも調べる
	if (PairPoke_GetInfo_BigSize(fldobj)){
		u8 dir = FieldOBJ_DirDispGet( fldobj );
		if ( (dir == DIR_LEFT)||(dir == DIR_RIGHT) ){
			//検索座標を取得
			PairPoke_GetBackPos(fldobj, &x, &z);
			attr = GetAttributeLSB( fsys, x, z );
			if( MATR_IsGrass(attr) == TRUE ){
				FE_FldOBJGrass_AddXZ( fldobj, TRUE, x, z, TRUE );		//2番目の引数はFALSE（アニメなし追加）がよかったが、目立たないので対処せず。ROM作ってからきづいた・・
			}else if(  MATR_IsLongGrass(attr) == TRUE ){
				FE_FldOBJLGrass_AddXZ( fldobj, TRUE, x, z, TRUE );		//2番目の引数はFALSE（アニメなし追加）がよかったが、目立たないので対処せず。ROM作ってからきづいた・・
			}
		}
	}
}
#endif	//GRASS_ADD_VALID